package com.common.base.utils

/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：28/8/2025
 *
 * 描述：单位转换
 *
 * 修订历史：
 *
 */
object UnitConversionUtils {

    /**
     * 长度单位（内部统一以米为基准）
     */
    enum class LengthUnit(val toMeter: Double) {
        CM(0.01),        // 厘米
        M(1.0),          // 米
        KM(1000.0),      // 千米
        MI(1609.344),    // 英里（statute mile）
        FT(0.3048),      // 英尺
        IN(0.0254);      // 英寸
    }

    /**
     * 重量单位（内部统一以千克为基准）
     */
    enum class WeightUnit(val toKilogram: Double) {
        G(0.001),           // 克
        KG(1.0),            // 千克
        LB(0.45359237);     // 磅（国际常用，1 lb = 0.45359237 kg）
    }

    /**
     * 温度单位（使用摄氏度为中间单位进行转换）
     */
    enum class TemperatureUnit {
        C, // 摄氏度
        F  // 华氏度
    }

    /**
     * 按枚举进行转换
     * @param value 长度值
     * @param from 源单位
     * @param to 目标单位
     * @return 转换后的值
     */
    @JvmStatic
    fun convertLength(value: Double, from: LengthUnit, to: LengthUnit): Double {
        if (from == to) return value
        val meters = value * from.toMeter
        return meters / to.toMeter
    }

    /**
     * 按字符串单位进行转换（支持中文与常见缩写）
     * 支持的单位：
     * - 中文：厘米、米、千米/公里、英里、英尺、英寸
     * - 英文/缩写：cm, m, km, mi/mile, ft/foot/feet, in/inch
     *
     * @throws IllegalArgumentException 当单位无法识别时
     */
    @JvmStatic
    fun convertLength(value: Double, fromLabel: String, toLabel: String): Double {
        val from = parseLengthUnit(fromLabel)
            ?: throw IllegalArgumentException("无法识别的源单位: $fromLabel")
        val to = parseLengthUnit(toLabel)
            ?: throw IllegalArgumentException("无法识别的目标单位: $toLabel")
        return convertLength(value, from, to)
    }

    /**
     * 将单位字符串解析为 LengthUnit
     */
    @JvmStatic
    fun parseLengthUnit(label: String): LengthUnit? {
        val key = label.trim().lowercase(java.util.Locale.ROOT)
        return when (key) {
            // 厘米
            "厘米", "公分", "cm" -> LengthUnit.CM
            // 米
            "米", "m" -> LengthUnit.M
            // 千米 / 公里
            "千米", "公里", "km" -> LengthUnit.KM
            // 英里
            "英里", "mi", "mile" -> LengthUnit.MI
            // 英尺
            "英尺", "ft", "foot", "feet" -> LengthUnit.FT
            // 英寸
            "英寸", "in", "inch" -> LengthUnit.IN
            else -> null
        }
    }

    /**
     * 重量转换（枚举）
     */
    @JvmStatic
    fun convertWeight(value: Double, from: WeightUnit, to: WeightUnit): Double {
        if (from == to) return value
        val kilograms = value * from.toKilogram
        return kilograms / to.toKilogram
    }

    /**
     * 重量转换（字符串单位，支持中文与常见缩写）
     */
    @JvmStatic
    fun convertWeight(value: Double, fromLabel: String, toLabel: String): Double {
        val from = parseWeightUnit(fromLabel)
            ?: throw IllegalArgumentException("无法识别的源单位: $fromLabel")
        val to = parseWeightUnit(toLabel)
            ?: throw IllegalArgumentException("无法识别的目标单位: $toLabel")
        return convertWeight(value, from, to)
    }

    /**
     * 解析重量单位
     */
    @JvmStatic
    fun parseWeightUnit(label: String): WeightUnit? {
        val key = label.trim().lowercase(java.util.Locale.ROOT)
        return when (key) {
            // 千克
            "千克", "公斤", "kg", "kilogram" -> WeightUnit.KG
            // 克
            "克", "g", "gram" -> WeightUnit.G
            // 磅
            "磅", "lb", "lbs", "pound", "pounds" -> WeightUnit.LB
            else -> null
        }
    }

    /**
     * 温度转换（枚举方式）
     * @param value 温度值
     * @param from 源单位
     * @param to 目标单位
     * @return 转换后的温度值
     */
    @JvmStatic
    fun convertTemperature(value: Double, from: TemperatureUnit, to: TemperatureUnit): Double {
        if (from == to) return value
        val celsius = when (from) {
            TemperatureUnit.C -> value
            TemperatureUnit.F -> (value - 32.0) * 5.0 / 9.0
        }
        return when (to) {
            TemperatureUnit.C -> celsius
            TemperatureUnit.F -> celsius * 9.0 / 5.0 + 32.0
        }
    }

    /**
     * 温度转换（字符串单位，支持中文、英文及符号）
     * 支持：摄氏度/℃/°C/C/celsius；华氏度/℉/°F/F/fahrenheit
     *
     * @throws IllegalArgumentException 当单位无法识别时
     */
    @JvmStatic
    fun convertTemperature(value: Double, fromLabel: String, toLabel: String): Double {
        val from = parseTemperatureUnit(fromLabel)
            ?: throw IllegalArgumentException("无法识别的源单位: $fromLabel")
        val to = parseTemperatureUnit(toLabel)
            ?: throw IllegalArgumentException("无法识别的目标单位: $toLabel")
        return convertTemperature(value, from, to)
    }

    /**
     * 解析温度单位
     */
    @JvmStatic
    fun parseTemperatureUnit(label: String): TemperatureUnit? {
        val key = label.trim().lowercase(java.util.Locale.ROOT)
        return when (key) {
            "摄氏度", "c", "celsius", "℃", "°c" -> TemperatureUnit.C
            "华氏度", "f", "fahrenheit", "℉", "°f" -> TemperatureUnit.F
            else -> null
        }
    }
}